/**
 * Class MyDebuger
 * 
 * @brief Clase para manejar depuracion y errores JS
 * @author Hermann D. Schimpf <hschimpf@gschimpf.com>
 * @license http://opensource.org/licenses/gpl-2.0.php
 * @date 2010-01-06
 * @version 0.1.0
 */
function MyDebuger() {
	/* verificamos si se especifico un primer parametro como funcion */
	if (arguments[0] !== undefined) {
		/* verificamos si la funcion que se desea llamar esta definida */
		if (this[arguments[0]] !== undefined) {
			/* creamos una variable donde armamos la cadena */
			var evalString = 'this.' + arguments[0] + '(';
			/* verificamos si se especificaron parametros */
			if (arguments[1] !== undefined) {
				/* creamos una bandera */
				var first = true;
				/* obtenemos los parametros para la funcion */
				for ( var i = 1; i < arguments.length; i++) {
					/* verificamos si es el primer parametro a agregar */
					if (first === true) {
						/* modificamos el parametro */
						first = false;
					} else {
						/* agregamos una coma a la cadena */
						evalString += ', ';
					}
					/* agregamos el argumento a la cadena */
					evalString += /*
					 * verificamos si es un string para agregarlo
					 * entre comillas
					 */
					typeof arguments[i] === 'string' ?
					/* agregamos el string */
					'\'' + arguments[i] + '\'' :
					/* agregamos el parametro como esta */
					arguments[i];
				}
			}
			/* finalizamos la cadena */
			evalString += ');';
			/* llamamos a la funcion con los parametros */
			eval(evalString);
		}
	}
};
MyDebuger.prototype = new HTMLFormater;
/* version de la clase */
MyDebuger.prototype.version = 0;
/* subversion de la clase */
MyDebuger.prototype.subversion = 1;
/* numero de revision de la clase */
MyDebuger.prototype.revision = 0;
/* nombre de la instancia */
MyDebuger.prototype.name = false;
/* bandera para des / habilitar la salida de depuracion */
MyDebuger.prototype.debugStat = false;
/* bandera para ver si se creo la instancia llamando a parent */
MyDebuger.prototype.created = false;
/* atributo de tiempo de ejecucion inicial */
MyDebuger.prototype.timeStart = 0;
/* atributo de tiempo de ejecucion actual */
MyDebuger.prototype.timeNow = 0;
/* cadena para mensajes */
MyDebuger.prototype.cadenaShow = '';
/* bandera para el salto */
MyDebuger.prototype.saltoMsg = false;
MyDebuger.prototype.getVersion = function() {
	/* retornamos la version actual de la clase */
	return 'v' + this.version + '.' + this.subversion + '.' + this.revision;
};
MyDebuger.prototype.__construct = function(debug, name, version) {
	/* modificamos la bandera */
	this.created = true;
	/* almacenamos el parametro name */
	this.saveName(name);
	/* almacenamos el parametro debug */
	this.saveDebugStatus(debug);
	/* almacenamos el tiempo de inicio */
	this.saveTime();
	/* inicializamos los mensajes */
	this.inicializarMensajes(version);
};
MyDebuger.prototype.inicializarMensajes = function(version) {
	/* mostramos un mensaje */
	this.show('Habilitando depuracion..', false);
	/* mostramos ok al mensaje */
	this.showOK();
	/* mostramos un mensaje */
	this.show('Version de la clase: ' + this.blue(version));
};
MyDebuger.prototype.saveDebugStatus = function(debug) {
	/* asignamos al parametro 'debug' un valor */
	this.debugStat = /* verificamos si se especifico un valor */
	typeof debug !== 'undefined' ? (
	/* verificamos si se especifico True */
	debug === true ?
	/* almacenamos True */
	true :
	/* almacenamos False */
	false
	/* almacenamos False */
	) : false;
	/* verificamos si se habilito la depuracion */
	if (this.debugStat === true)
		/* creamos el div para depuracion */
		this.crearDepuracion();
};
MyDebuger.prototype.getTamanoVentana = function() {
	var w, h;
	/* verificamos si tenemos la propiedad 'innerHeight' */
	if (typeof window.innerHeight == 'number') {
		/* obtenemos el ancho */
		w = window.innerWidth;
		/* obtenemos el largo */
		h = window.innerHeight;
		/* sino, obtenemos desde la propiedad 'clientHeight' */
	} else if (document.body && document.body.clientHeight) {
		/* obtenemos el ancho */
		w = document.body.clientWidth;
		/* obtenemos el largo */
		h = document.body.clientHeight;
	}
	/* retornamos un array con el largo y ancho */
	return Array(w, h);
};
MyDebuger.prototype.getScroll = function() {
	/* retornamos la posicion del scroll */
	return document.body.scrollTop == 0 ? document.documentElement.scrollTop : document.body.scrollTop;
};
MyDebuger.prototype.getTopMsg = function() {
	/* retornamos la posicion top para el mensaje */
	return this.getScroll() + 'px';
};
MyDebuger.prototype.getWidthMsg = function(menos) {
	/* obtenemos y retornamos el tamano para el div */
	return this.getTamanoVentana()[0] - (menos === false ? 0 : 32) + 'px';
};
MyDebuger.prototype.crearDepuracion = function() {
	/* creamos el div donde mostramos los mensajes */
	var divDepuracion = this.crearDivDepuracion();
	/* agregamos el div al body */
	document.body.appendChild(divDepuracion);
	/* creamos una variable */
	var instancia = this;
	/* agregamos un evento para mover el div */
	window.top.onscroll = function() {
		/* ejecutamos la funcion que mueve el div */
		divDepuracion.style.top = instancia.getTopMsg(divDepuracion.offsetHeight);
	};
};
MyDebuger.prototype.crearDivDepuracion = function() {
	/* creamos un elemento DIV */
	var div = document.createElement('DIV');
	/* le agregamos una propiedad al elemento */
	div.estado = false;
	/* le agregamos una funcion al elemento */
	div.ocultar = function() {
		/* verificamos si salimos de la ejecucion */
		if (div.estado === false)
			/* salimos de la ejecucion */
			return true;
		/* ingresamos a un bucle */
		for ( var hide = substr(div.style.height, 0, -2) / 10, time = 0; hide >= 1; hide -= 0.2, time += 5)
			/* creamos un trigger */
			setTimeout('with(document.getElementById(\'mensajes::debug\')) {style.opacity = ' + (hide / 40 > 0.4 && hide / 40 < 0.9 ? hide / 40 : hide / 40 < 0.9 ? 0.4 : 0.9) + ';style.height = \'' + hide * 10 + 'px\';}', time);
	};
	/* le agregamos una funcion al elemento */
	div.mostrar = function() {
		/* vaciamos la bandera */
		div.estado = false;
		/* ingresamos a un bucle */
		for ( var show = substr(div.style.height, 0, -2) / 10, time = 0; show <= 40; show += 0.2, time += 3)
			/* creamos un trigger */
			setTimeout('with(document.getElementById(\'mensajes::debug\')) {style.opacity = ' + (show / 40 < 0.9 ? show / 40 : 0.9) + ';style.height = \'' + show * 10 + 'px\';}', time);
	};
	/* asignamos las propiedades */
	with (div) {
		/* le asignamos un id */
		setAttribute('id', 'mensajes::debug');
		/* asignamos los estilos */
		with (style) {
			/* asignamos un color de fondo */
			backgroundColor = '#DDD';
			/* asignamos una transparencia */
			opacity = 0.4;
			/* asignamos la posicion */
			position = 'absolute';
			/* asignamos el left del div */
			left = 0;
			/* asignamos el top del div */
			top = 0;
			/* asignamos el tamano del div */
			width = this.getWidthMsg();
			/* asignamos el tamano del div */
			height = '10px';
			/* asignamos 0 al zIndex para que este frente a todo */
			zIndex = 0;
			/* habilitamos la barra de movimiento vertical */
			overflowY = 'scroll';
			/* ocultamos la barra de movimiento horizontal */
			overflowX = 'hidden';
			/* dejamos un borde de espacio */
			padding = '8px';
		}
		/*
		 * agregamos el evento onmouseover para llamar a la funcion del elemento
		 */
		addEventListener('mouseover', function() {
			this.mostrar();
		}, false);
		/*
		 * agregamos el evento onmouseout para llamar a la funcion del elemento
		 */
		addEventListener('mouseout', function() {
			this.estado = setTimeout(this.ocultar, 1000);
		}, false);
	}
	/* retornamos el div creado */
	return div;
};
MyDebuger.prototype.saveName = function(name) {
	/* almacenamos el nombre de la instancia */
	this.name = /* verificamos si se especifico un valor */
	name !== undefined ?
	/* almacenamos el nombre */
	name :
	/* almacenamos el nombre de esta clase */
	"MyDebuger";
};
MyDebuger.prototype.saveTime = function() {
	/* guardamos el tiempo de inicio */
	this.timeStart = this.getTime();
};
MyDebuger.prototype.getTime = function() {
	/* creamos una instancia de Date */
	var fecha = new Date;
	/* retornamos el tiempo actual en milisegundos */
	return fecha.getTime() / 1000;
};
MyDebuger.prototype.getTimeNow = function() {
	/* agregamos el tiempo transcurrido al tiempo actual */
	this.timeNow = this.getTime() - this.timeStart;
	/* retornamos el tiempo con formato de 3 decimales y 6 digitos */
	return str_pad(number_format(this.timeNow, 3, ',', '.'), 7, '0', 'STR_PAD_LEFT');
};
MyDebuger.prototype.getName = function() {
	/* retornamos el nombre de la clase */
	return this.name;
};
MyDebuger.prototype.show = function(stringMsg, breaker) {
	/* almacenamos la cadena */
	this.cadenaShow = stringMsg;
	/* armamos la cadena de salida y la mostramos */
	this.armarMostrarCadena(breaker);
	/* modificamos la bandera */
	this.saltoMsg = /* verificamos si es un salto */
	breaker === true || typeof breaker == 'undefined' ?
	/* almacenamos false */
	false :
	/* almacenamos true */
	true;
};
MyDebuger.prototype.showOK = function(withColor) {
	/* mostramos la cadena OK */
	this.show(withColor === true || typeof withColor == 'undefined' ? this.green('OK') : 'OK', true);
};
MyDebuger.prototype.armarMostrarCadena = function(breaker) {
	/* agregamos el titulo y tiempo a la cadena */
	this.agregarTituloTiempo();
	/* formateamos la cadena con HTML */
	this.formatearCadena(breaker);
	/* verificamos si esta habilitada la bandera de depuracion */
	if (this.debugStat === true) {
		/* agregamos la cadena al div de depuracion */
		this.mostrarCadena();
	}
};
MyDebuger.prototype.mostrarCadena = function() {
	/* obtenemos el div */
	var divMsj = document.getElementById('mensajes::debug');
	/* agregamos la cadena al div */
	divMsj.innerHTML += this.cadenaShow;
};
MyDebuger.prototype.agregarTituloTiempo = function() {
	/* almacenamos la cadena con el titulo y el tiempo actual */
	this.cadenaShow = (
	/* verificamos si mostramos el nombre */
	this.saltoMsg === false ?
	/* agregamos el tiempo y nombre de la clase */
	'[' + this.getTimeNow() + ' ' + this.getName() + '::debug] ' :
	/* no agregamos nada */
	''
	/* agregamos la cadena */
	) + this.cleanHTML(this.cadenaShow);
};
MyDebuger.prototype.formatearCadena = function(breaker) {
	/* formateamos la cadena dentro de la etiquera CODE */
	this.cadenaShow = '<code>' + this.cadenaShow + '</code>';
	/* agregamos el salto de linea a la cadena */
	this.agregarSaltoLinea(breaker);
};
MyDebuger.prototype.agregarSaltoLinea = function(breaker) {
	/* verificamos si esta habilitada la bandera de salto de linea */
	if (breaker === true || typeof breaker == 'undefined')
		/* agregamos el salto a la cadena */
		this.cadenaShow += '<br/>';
	/* si no */
	else
		/* agregamos un espacio */
		this.cadenaShow += ' ';
};
MyDebuger.prototype.newException = function(e) {
	/* enviamos una excepcion para mostrar el mensaje */
	throw new Error(e);
};